package com.bwie.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bwie.mapper.TbMenuMapper;
import com.bwie.mapper.TbRoleMapper;
import com.bwie.pojo.TbMenu;
import com.bwie.pojo.TbRole;
import com.bwie.pojo.TbUser;
import com.bwie.service.TbUserService;
import com.bwie.mapper.TbUserMapper;
import com.bwie.utils.MobileMessageUtil;
import com.bwie.utils.R;
import com.bwie.vo.LoginVo;
import com.bwie.vo.PageInfoVo;
import com.bwie.vo.RegInfoVo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* @author Lenovo
* @description 针对表【tb_user(用户表)】的数据库操作Service实现
* @createDate 2025-07-18 14:22:09
*/
@Service
@Slf4j
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser>
    implements TbUserService{

    @Autowired
    private TbUserMapper tbUserMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private TbMenuMapper tbMenuMapper;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private TbRoleMapper tbRoleMapper;


    @Override
    public R sendCode(String mobile) {

        boolean mobile1 = Validator.isMobile(mobile);
        if(!mobile1){
            return R.ERROR(4500,"手机格式错误");
        }
        String numbers = RandomUtil.randomNumbers(4);
        log.info("code-"+mobile);

        String key="code-"+mobile;
        redisTemplate.opsForValue().set(key,numbers,5, TimeUnit.MINUTES);

        MobileMessageUtil.sendMobileMessage(mobile,numbers);

        return R.OK();
    }

    @Override
    public R userReg(RegInfoVo regInfoVo) {
        TbUser tbUser = tbUserMapper.selectOne(new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserMobile, regInfoVo.getMobile()));
        if(tbUser!=null){
            return R.ERROR(4500,"用户已存在");
        }
        String key="code-"+regInfoVo.getMobile();
        String code = redisTemplate.opsForValue().get(key);
        if(code==null){
            return R.ERROR(4500,"验证码已过期");
        }
        if(!code.equals(regInfoVo.getCode())){
            return R.ERROR(4500,"验证码错误");
        }

        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String encode = encoder.encode(regInfoVo.getPass());

        TbUser user = new TbUser();
        user.setUserMobile(regInfoVo.getMobile());
        user.setUserPass(encode);
        user.setUserName("匿名它会");
        user.setCreateBy("系统");
        user.setCreateTime(new Date());
        tbUserMapper.insert(user);

        return R.OK();
    }

    @Override
    public R userLogin(LoginVo loginVo) {
        TbUser tbUser = tbUserMapper.selectOne(new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserMobile, loginVo.getMobile()));
        if(tbUser==null){
            return R.ERROR(4500,"用户未注册");
        }
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        encoder.encode(loginVo.getPass());
        //参数在前,对象在后,否则密码错误
        boolean matches = encoder.matches(loginVo.getPass(),tbUser.getUserPass());
        if(!matches){
            return R.ERROR(500,"密码错误");
        }

        String token = Jwts.builder().signWith(SignatureAlgorithm.HS256, "123456").claim("userId", tbUser.getUserId()).claim("userName",tbUser.getUserName()).compact();
        redisTemplate.opsForValue().set("token-"+tbUser.getUserId(),token,60,TimeUnit.MINUTES);

        List<String> roleName = tbRoleMapper.getRoleByUserId(tbUser.getUserId());

        tbUser.setRoleName(roleName);
        tbUser.setToken(token);
        tbUser.setUserPass(null);

        return R.OK(tbUser);
    }

    @Override
    public R getTreeList() {
        String token = request.getHeader("token");
        if(token==null){
            return R.ERROR(500,"请先登录");
        }
        Claims body = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
        Integer userId = body.get("userId", Integer.class);
        List<TbMenu> menuList = tbMenuMapper.getMenuByUserId(userId);
        List<Tree<String>> treeList = TreeUtil.build(menuList, "0", (tree, menu) -> {
            menu.setId(tree.getMenuId()+"");
            menu.setName(tree.getMenuName());
            menu.setParentId(tree.getMenuPid()+"");
            menu.putExtra("path",tree.getMenuPath());
        });
        return R.OK(treeList);
    }

    @Override
    public R getUserList(PageInfoVo pageInfoVo) {
        Page<TbUser> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());
        Page<TbUser> userList = tbUserMapper.getUserList(page, pageInfoVo);
        return R.OK(userList);
    }

    @Override
    public R getUserInfoByUserId(Integer userId) {
        TbUser tbUser = tbUserMapper.selectById(userId);
        if(tbUser==null){
            return R.ERROR(500,"用户不存在");
        }
        return R.OK(tbUser);
    }
}




